#include "face_beauty_dialog.h"

#include <QtWidgets/QFileDialog>
#include <QtMultimedia/QCameraInfo>
#include <QtMultimedia/QCameraImageCapture>
#include <QtMultimedia/QImageEncoderSettings>

FaceBeautyDialog::FaceBeautyDialog(): ui_(new Ui_Dialog()), photo_opened_(false)
{
    ui_->setupUi(this);


    SetupSignal();
    SetupFilter();
    SetupCamera();
}

FaceBeautyDialog::~FaceBeautyDialog()
{
    if(filter_) filter_->quit();
}

void FaceBeautyDialog::SetupSignal()
{
    QObject::connect(ui_->buffingHorizontalSlider,&QSlider::valueChanged, this, &FaceBeautyDialog::BuffingValueChanged);
    QObject::connect(ui_->whiteningHorizontalSlider,&QSlider::valueChanged, this, &FaceBeautyDialog::WhiteningValueChanged);
    QObject::connect(ui_->thinFaceHorizontalSlider,&QSlider::valueChanged, this, &FaceBeautyDialog::ThinFaceValueChanged);
    QObject::connect(ui_->bigEyeHorizontalSlider,&QSlider::valueChanged, this, &FaceBeautyDialog::BigEyeValueChanged);

    QObject::connect(ui_->openPhotoButton,&QPushButton::clicked, this, &FaceBeautyDialog::OpenPhoto);
    QObject::connect(ui_->openCameraButton,&QPushButton::clicked, this, &FaceBeautyDialog::OpenCamera);
}

void FaceBeautyDialog::SetupFilter()
{
    filter_.reset(new ImageFilterWorker);
    filter_->InitHandler(ui_->openGLWidget);
    filter_->start();
}

void FaceBeautyDialog::SetupCamera()
{
    //Camera devices:
    const QList<QCameraInfo> availableCameras = QCameraInfo::availableCameras();
    for (const QCameraInfo &cameraInfo : availableCameras) {
        ui_->cameraComboBox->addItem(cameraInfo.description(), QVariant::fromValue(static_cast<void*>(new QCameraInfo(cameraInfo))));
    }

    view_finder_.reset(new FaceBeautyViewFinder(filter_.get()));
}

void FaceBeautyDialog::PhotoReopen()
{
    QImage *img = new QImage(photo_opened_path_);
    filter_->ProccessFrame(img);
}

int FaceBeautyDialog::PaintImage(QImage *img)
{
    ui_->openGLWidget->ProccessFrame(img);
    return 0;
}

void FaceBeautyDialog::BuffingValueChanged()
{
    ui_->buffingLineEdit->setText(QString::number(ui_->buffingHorizontalSlider->value()));

    if(filter_) {
        filter_->SetFeatureQuality(facebeauty::FACE_BEAUTY_FEATURE_BUFFING,ui_->buffingHorizontalSlider->value());

        if(photo_opened_)  PhotoReopen();
    }

}

void FaceBeautyDialog::WhiteningValueChanged()
{
    ui_->whiteningLineEdit->setText(QString::number(ui_->whiteningHorizontalSlider->value()));

    if(filter_) {
        filter_->SetFeatureQuality(facebeauty::FACE_BEAUTY_FEATURE_WHITENING,ui_->whiteningHorizontalSlider->value());

        if(photo_opened_)  PhotoReopen();
    }
}

void FaceBeautyDialog::ThinFaceValueChanged()
{

    ui_->thinFaceLineEdit->setText(QString::number(ui_->thinFaceHorizontalSlider->value()));

    if(filter_) {
        filter_->SetFeatureQuality(facebeauty::FACE_BEAUTY_FEATURE_THINFACE,ui_->thinFaceHorizontalSlider->value());

        if(photo_opened_)  PhotoReopen();
    }
}

void FaceBeautyDialog::BigEyeValueChanged()
{
    ui_->bigEyeLineEdit->setText(QString::number(ui_->bigEyeHorizontalSlider->value()));

    if(filter_) {
        filter_->SetFeatureQuality(facebeauty::FACE_BEAUTY_FEATURE_BIGEYE, ui_->bigEyeHorizontalSlider->value());

        if(photo_opened_)  PhotoReopen();
    }
}


bool FaceBeautyDialog::OpenPhoto()
{
    CloseCamera();

    photo_opened_path_ = QFileDialog::getOpenFileName(this, tr("Open File"), "./", tr("Images (*.png *.jpeg *.jpg *jp2)"));
    ui_->openPhotoLineEdit->setText(photo_opened_path_);
    QImage *img = new QImage(photo_opened_path_);

    filter_->quit();
    filter_->Reset();
    filter_->InitModule(0xfffffff, img->width(), img->height(), facebeauty::FACE_BEAUTY_COLOR_SPACE_YUV_I420_PLANAR);
    filter_->start();

    filter_->ProccessFrame(img);

    photo_opened_ = true;

    return true;
}

bool FaceBeautyDialog::OpenCamera()
{
    QCameraInfo* info = static_cast<QCameraInfo*>(ui_->cameraComboBox->currentData().value<void*>());
    QCamera* c = new QCamera(*info, this);

    if(!c) return false;
    camera_.reset(c);

    QObject::connect(camera_.get(), &QCamera::statusChanged, this, &FaceBeautyDialog::CameraStatusChanged);

    camera_->setViewfinder(view_finder_.get());
    camera_->start();

    photo_opened_ = false;

    return true;
}

void FaceBeautyDialog::CameraStatusChanged(QCamera::Status s)
{
    if(s != QCamera::LoadedStatus) {
        return;
    }

    QList<QSize> resolutions = camera_->supportedViewfinderResolutions();

    if(resolutions.empty()) {
        return;
    }

    filter_->quit();
    filter_->Reset();
    filter_->InitModule(0xfffffff, resolutions.last().width(), resolutions.last().height(), facebeauty::FACE_BEAUTY_COLOR_SPACE_YUV_I420_PLANAR);
    filter_->start();

    return;
}

void FaceBeautyDialog::CloseCamera()
{
    if(!camera_)  return;

    camera_->stop();
}
